package com.itheima.tliasmanagementspringboot.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 演示通知顺序
 */
@Component
//@Aspect
@Slf4j
@Order(1)//控制优先级,数字越小优先级越高
public class Aspect5 {
    @Autowired
    HttpServletRequest httpServletRequest;

    //定义一个切入点表达式,抽取重复的表达式
    @Pointcut("execution(* com.itheima.tliasmanagementspringboot.service.*.*(..))")
    public void point(){}

    //service层所有类中的所有方法中的加了Log注解的方法加入切入点(会被切面增强的方法)
    /*@Before("point() && @annotation(com.itheima.tliasmanagementspringboot.annotation.Log)")
    public void before(){

        log.info("前置通知");
    }*/

    //service层所有类中的所有方法
    @Before("point()")
    public void before(JoinPoint jp){
        log.info("前置通知");
        //获取目标类名
        log.info("目标类名: {}", jp.getTarget().getClass().getName());
        //方法名
        log.info("方法名: {}", jp.getSignature().getName());
        //方法返回值类型
        //向下转型,子类有更多的方法
        MethodSignature signature = (MethodSignature)jp.getSignature();
        log.info("方法的返回值类型: {}", signature.getReturnType());
        //方法参数
        log.info("方法参数: {}", jp.getArgs());
        //方法上的注解
        Method method = signature.getMethod();//这个地方是对应的接口上的注解
        log.info("方法上的注解: {}", method.getAnnotations());
        //获取请求路径
        //先要注入HttpServletRequest
        log.info("请求路径为: {}", httpServletRequest.getRequestURL());//带协议,ip,端口号

    }
}
